﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Collections.Generic;

namespace BezierSegmentDemo
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        private readonly Random random;
        private bool isAnimated;
        private double speed;

        // note: no INotifyPropertyChanged for this very basic example...
        public double Speed
        {
            get
            {
                return this.speed;
            }
            set
            {
                this.speed = value;
            }
        }

        public bool IsAnimated
        {
            get
            {
                return this.isAnimated;
            }
            set
            {
                this.isAnimated = value;
                if (value)
                {
                    this.AnimateAll();
                }
            }
        }

        public Window1()
        {
            InitializeComponent();

            this.DataContext = this;
            this.Speed = 1;

            this.random = new Random((int)DateTime.Now.Ticks);
            this.MouseLeftButtonDown += Canvas_MouseLeftButtonDown;
            this.MouseDoubleClick += Window1_MouseDoubleClick;
        }

        private void Window1_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.canvas.IsMouseCaptured)
            {
                this.canvas.ReleaseMouseCapture();
            }
        }

        private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (!this.canvas.IsMouseCaptured)
            {
                this.canvas.CaptureMouse();
            }

            this.customFigure.AddPoint(e.GetPosition(this.canvas));
        }

        private PointAnimation CreateRandomPointAnimation()
        {
            // create a PointAnimation that can animate a point in the window
            return new PointAnimation(new Point(
                this.random.NextDouble() * this.ActualWidth,
                this.random.NextDouble() * this.ActualHeight),
                TimeSpan.FromSeconds(this.Speed));
        }

        private void AnimateAll()
        {
            // the first time the animations start, they will reset the binding set in
            // the BezierFigure control and drag will no longer work
            this.Animate(BezierFigure.StartPointProperty);
            this.Animate(BezierFigure.StartBezierPointProperty);
            this.Animate(BezierFigure.EndPointProperty);
            this.Animate(BezierFigure.EndBezierPointProperty);
        }

        private void Animate(DependencyProperty property)
        {
            var animation = this.CreateRandomPointAnimation();

            if (this.IsAnimated)
            {
                animation.Completed += (s, e) => this.Animate(property);
            }

            this.figure.BeginAnimation(property, animation);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        private void btnUp_Click(object sender, RoutedEventArgs e)
        {
            this.line.StartPoint = new Point(this.line.StartPoint.X, this.line.StartPoint.Y - 10);
            this.line.EndPoint = new Point(this.line.EndPoint.X, this.line.EndPoint.Y - 10);
        }

        private void btnDown_Click(object sender, RoutedEventArgs e)
        {
            this.line.StartPoint = new Point(this.line.StartPoint.X, this.line.StartPoint.Y + 10);
            this.line.EndPoint = new Point(this.line.EndPoint.X, this.line.EndPoint.Y + 10);
        }

        private void btnLeft_Click(object sender, RoutedEventArgs e)
        {
            this.line.StartPoint = new Point(this.line.StartPoint.X - 10, this.line.StartPoint.Y);
            this.line.EndPoint = new Point(this.line.EndPoint.X - 10, this.line.EndPoint.Y);
        }

        private void btnRight_Click(object sender, RoutedEventArgs e)
        {
            this.line.StartPoint = new Point(this.line.StartPoint.X + 10, this.line.StartPoint.Y);
            this.line.EndPoint = new Point(this.line.EndPoint.X + 10, this.line.EndPoint.Y);
        }
    }
}
